//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <winhack.h>
#include "framebuffer.h"
#include "simulator.h"

EXTERN bool g_isSimulator;
EXTERN BYTE* g_sharedMemoryAddress;

void CFrameBuffer::BaseplaneBufferCopy_RGB888(Int32 x,Int32 y,Int32 width,Int32 height)
{
    DWORD * pSrcBuffer = (DWORD *)m_bpBufferAddress;
    DWORD * pDesBuffer = (DWORD *)m_pSurface->pixels;

    pSrcBuffer+=y*m_screenWidth+x;
    pDesBuffer+=(m_screenPosY+y)*m_mobileWidth+x+ m_screenPosX;
    
    for (int jSrc = 0; jSrc < height; jSrc++) {
        for (int iSrc = 0; iSrc < width; iSrc++) {
            *pDesBuffer = *pSrcBuffer;
            pSrcBuffer++;
            pDesBuffer++;
        }
        pDesBuffer += (m_mobileWidth - width);
        pSrcBuffer += (m_screenWidth - width);
    }

    if (g_isSimulator) {
        SimulatorInfo* simulatorInfo = (SimulatorInfo*)g_sharedMemoryAddress;
        if (simulatorInfo->simulatoHostStarted) {
            switch (simulatorInfo->colorFormat) {
                case COLOR_RGB24:BaseplaneOverlayCopy_888to888(); break;
                case COLOR_RGB565:BaseplaneOverlayCopy_565to888(); break;
                case COLOR_RGBT555:BaseplaneOverlayCopy_555to888(); break;
                case COLOR_RGBT666:BaseplaneOverlayCopy_666to888(); break;
                default:break;
            }
        }
    }
}

void CFrameBuffer::BaseplaneBufferCopy_RGB565(Int32 x,Int32 y,Int32 width,Int32 height)
{
    WORD * pSrcBuffer = (WORD *)m_bpBufferAddress;
    DWORD * pDesBuffer = (DWORD *)m_pSurface->pixels;

    pSrcBuffer+=y*m_screenWidth+x;
    pDesBuffer+=(m_screenPosY+y)*m_mobileWidth+x+ m_screenPosX;
    
    for (int jSrc = 0; jSrc < height; jSrc++) {
        for (int iSrc = 0; iSrc < width; iSrc++) {
            *pDesBuffer = ColorRGB565ToRGB888(*pSrcBuffer);
            pSrcBuffer++;
            pDesBuffer++;
        }
        pDesBuffer += (m_mobileWidth - width);
        pSrcBuffer += (m_screenWidth - width);
    }

    if (g_isSimulator) {
        SimulatorInfo* simulatorInfo = (SimulatorInfo*)g_sharedMemoryAddress;
        if (simulatorInfo->simulatoHostStarted) {
            switch (simulatorInfo->colorFormat) {
                case COLOR_RGB24:BaseplaneOverlayCopy_888to888(); break;
                case COLOR_RGB565:BaseplaneOverlayCopy_565to888(); break;
                case COLOR_RGBT555:BaseplaneOverlayCopy_555to888(); break;
                case COLOR_RGBT666:BaseplaneOverlayCopy_666to888(); break;
                default:break;
            }
        }
    }
}

void CFrameBuffer::BaseplaneBufferCopy_RGBT555(Int32 x,Int32 y,Int32 width,Int32 height)
{
    WORD * pSrcBuffer = (WORD *)m_bpBufferAddress;
    DWORD * pDesBuffer = (DWORD *)m_pSurface->pixels;

    pSrcBuffer+=y*m_screenWidth+x;
    pDesBuffer+=(m_screenPosY+y)*m_mobileWidth+x+ m_screenPosX;
    
    for (int jSrc = 0; jSrc < height; jSrc++) {
        for (int iSrc = 0; iSrc < width; iSrc++) {
            *pDesBuffer = ColorRGBT555ToRGB888(*pSrcBuffer);
            pSrcBuffer++;
            pDesBuffer++;
        }
        pDesBuffer += (m_mobileWidth - width);
        pSrcBuffer += (m_screenWidth - width);
    }

    if (g_isSimulator) {
        SimulatorInfo* simulatorInfo = (SimulatorInfo*)g_sharedMemoryAddress;
        if (simulatorInfo->simulatoHostStarted) {
            switch (simulatorInfo->colorFormat) {
                case COLOR_RGB24:BaseplaneOverlayCopy_888to888(); break;
                case COLOR_RGB565:BaseplaneOverlayCopy_565to888(); break;
                case COLOR_RGBT555:BaseplaneOverlayCopy_555to888(); break;
                case COLOR_RGBT666:BaseplaneOverlayCopy_666to888(); break;
                default:break;
            }
        }
    }
}

void CFrameBuffer::BaseplaneBufferCopy_RGBT666(Int32 x,Int32 y,Int32 width,Int32 height)
{
    DWORD * pSrcBuffer = (DWORD *)m_bpBufferAddress;
    DWORD * pDesBuffer = (DWORD *)m_pSurface->pixels;

    pSrcBuffer+=y*m_screenWidth+x;
    pDesBuffer+=(m_screenPosY+y)*m_mobileWidth+x+ m_screenPosX;
    
    for (int jSrc = 0; jSrc < height; jSrc++) {
        for (int iSrc = 0; iSrc < width; iSrc++) {
            *pDesBuffer = ColorRGBT666ToRGB888(*pSrcBuffer);
            pSrcBuffer++;
            pDesBuffer++;
        }
        pDesBuffer += (m_mobileWidth - width);
        pSrcBuffer += (m_screenWidth - width);
    }

    if (g_isSimulator) {
        SimulatorInfo* simulatorInfo = (SimulatorInfo*)g_sharedMemoryAddress;
        if (simulatorInfo->simulatoHostStarted) {
            switch (simulatorInfo->colorFormat) {
                case COLOR_RGB24:BaseplaneOverlayCopy_888to888(); break;
                case COLOR_RGB565:BaseplaneOverlayCopy_565to888(); break;
                case COLOR_RGBT555:BaseplaneOverlayCopy_555to888(); break;
                case COLOR_RGBT666:BaseplaneOverlayCopy_666to888(); break;
                default:break;
            }
        }
    }
}

void CFrameBuffer::SetBasePlaneColorFormat(ColorFormat CFormat)
{
    if (COLOR_RGB24 == CFormat) {
        m_bpColorFormat = COLOR_RGB24;
        m_bpPixelBits = 32;
        m_bpPixelBytes = 4;
        m_screenColorBits = 32;
        m_bpBufferCopyFunc = &CFrameBuffer::BaseplaneBufferCopy_RGB888;
    }
    else if (COLOR_RGB565 == CFormat) {
        m_bpColorFormat = COLOR_RGB565;
        m_bpPixelBits = 16;
        m_bpPixelBytes = 2;
        m_screenColorBits = 16;
        m_bpBufferCopyFunc = &CFrameBuffer::BaseplaneBufferCopy_RGB565;
    }
    else if (COLOR_RGBT555 == CFormat) {
        m_bpColorFormat = COLOR_RGBT555;
        m_bpPixelBits = 16;
        m_bpPixelBytes = 2;
        m_screenColorBits = 16;
        m_bpBufferCopyFunc = &CFrameBuffer::BaseplaneBufferCopy_RGBT555;
    }
    else if (COLOR_RGBT666 == CFormat) {
        m_bpColorFormat = COLOR_RGBT666;
        m_bpPixelBits = 32;
        m_bpPixelBytes = 4;
        m_screenColorBits = 18;
        m_bpBufferCopyFunc = &CFrameBuffer::BaseplaneBufferCopy_RGBT666;
    }
    else {
        //wprintf(L"This format isn't supported! Use RGB565 instead!\n");
        m_bpColorFormat = COLOR_RGB565;
        m_bpPixelBits = 16;
        m_bpPixelBytes = 2;
        m_screenColorBits = 16;
        m_bpBufferCopyFunc = &CFrameBuffer::BaseplaneBufferCopy_RGB565;
    }
}

void CFrameBuffer::BaseplaneOverlayCopy_888to888(void)
{
    DWORD * pSrcBuffer = (DWORD *)(g_sharedMemoryAddress+sizeof(SimulatorInfo));
    DWORD * pDesBuffer = (DWORD *)m_pSurface->pixels;
    SimulatorInfo* simulatorInfo = (SimulatorInfo*)g_sharedMemoryAddress;

    pDesBuffer += (m_screenPosY +simulatorInfo->lcdOffsetY)*m_mobileWidth + m_screenPosX+simulatorInfo->lcdOffsetX;

    for (int i = 0; i < simulatorInfo->lcdHeight; i++) {
        for (int j = 0; j < simulatorInfo->lcdWidth; j++) {
            *pDesBuffer = *pSrcBuffer;
            //notice:(r,g,b) (0,0,0)->(0,0,1)
            if(!(*pDesBuffer)) *pDesBuffer = 1;
            pSrcBuffer++;
            pDesBuffer++;
        }
        pDesBuffer += (m_mobileWidth - simulatorInfo->lcdWidth);
    }
}

void CFrameBuffer::BaseplaneOverlayCopy_555to888(void)
{
    WORD * pSrcBuffer = (WORD *)(g_sharedMemoryAddress+sizeof(SimulatorInfo));
    DWORD * pDesBuffer = (DWORD *)m_pSurface->pixels;
    SimulatorInfo* simulatorInfo = (SimulatorInfo*)g_sharedMemoryAddress;

    pDesBuffer += (m_screenPosY +simulatorInfo->lcdOffsetY)*m_mobileWidth + m_screenPosX+simulatorInfo->lcdOffsetX;
    for (int i = 0; i < simulatorInfo->lcdHeight; i++) {
        for (int j = 0; j < simulatorInfo->lcdWidth; j++) {
            *pDesBuffer = ColorRGBT555ToRGB888(*pSrcBuffer);
            //notice:(r,g,b) (0,0,0)->(0,0,1)
            if(!(*pDesBuffer)) *pDesBuffer = 1;
            pSrcBuffer++;
            pDesBuffer++;
        }
        pDesBuffer += (m_mobileWidth - simulatorInfo->lcdWidth);
    }
}

void CFrameBuffer::BaseplaneOverlayCopy_565to888(void)
{
    WORD * pSrcBuffer = (WORD *)(g_sharedMemoryAddress+sizeof(SimulatorInfo));
    DWORD * pDesBuffer = (DWORD *)m_pSurface->pixels;
    SimulatorInfo* simulatorInfo = (SimulatorInfo*)g_sharedMemoryAddress;

    pDesBuffer += (m_screenPosY +simulatorInfo->lcdOffsetY)*m_mobileWidth + m_screenPosX+simulatorInfo->lcdOffsetX;
    for (int i = 0; i < simulatorInfo->lcdHeight; i++) {
        for (int j = 0; j < simulatorInfo->lcdWidth; j++) {
            *pDesBuffer = ColorRGB565ToRGB888(*pSrcBuffer);
            //notice:(r,g,b) (0,0,0)->(0,0,1)
            if(!(*pDesBuffer)) *pDesBuffer = 1;
            pSrcBuffer++;
            pDesBuffer++;
        }
        pDesBuffer += (m_mobileWidth - simulatorInfo->lcdWidth);
    }
}

void CFrameBuffer::BaseplaneOverlayCopy_666to888(void)
{
    DWORD * pSrcBuffer = (DWORD *)(g_sharedMemoryAddress+sizeof(SimulatorInfo));
    DWORD * pDesBuffer = (DWORD *)m_pSurface->pixels;
    SimulatorInfo* simulatorInfo = (SimulatorInfo*)g_sharedMemoryAddress;

    pDesBuffer += (m_screenPosY +simulatorInfo->lcdOffsetY)*m_mobileWidth + m_screenPosX+simulatorInfo->lcdOffsetX;
    for (int i = 0; i < simulatorInfo->lcdHeight; i++) {
        for (int j = 0; j < simulatorInfo->lcdWidth; j++) {
            *pDesBuffer = ColorRGBT666ToRGB888(*pSrcBuffer);
            //notice:(r,g,b) (0,0,0)->(0,0,1)
            if(!(*pDesBuffer)) *pDesBuffer = 1;
            pSrcBuffer++;
            pDesBuffer++;
        }
        pDesBuffer += (m_mobileWidth - simulatorInfo->lcdWidth);
    }
}
